package cn.sciento.farm.devicemanager.gateway.downlink.service;

import cn.sciento.farm.devicemanager.common.constant.DeviceConstant;
import cn.sciento.farm.devicemanager.common.constant.ResultConstant;
import cn.sciento.farm.devicemanager.gateway.model.downlink.AbstractBlockData;
import cn.sciento.farm.devicemanager.gateway.model.downlink.DownLinkResult;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author wumu
 * @version V1.0
 * @date 4/17/18
 * @time 10:08 AM
 */
public class MqttCallBackFuture {

    public MqttCallBackFuture(AbstractBlockData abstractBlockData) {
        this.abstractBlockData = abstractBlockData;
        futurePool.put(abstractBlockData.getBlockId(), this);
    }

    public static ConcurrentMap<String, MqttCallBackFuture> futurePool = new ConcurrentHashMap();

    private AbstractBlockData abstractBlockData;

    private int code = 0;

    private Object lock = new Object();

    private volatile boolean isDone = false;

    private String result ;

    public AbstractBlockData getAbstractBlockData() {
        return abstractBlockData;
    }

    public void setAbstractBlockData(AbstractBlockData abstractBlockData) {
        this.abstractBlockData = abstractBlockData;
    }

    public void setResponse(String status) {
        String generateStatus = abstractBlockData.generateStatus();
        if(generateStatus != null){
            if (!status.equals(abstractBlockData.generateStatus())) {
                return;
            }
        }
        this.result = status;
        code = 1;
        // notify future lock
        synchronized (lock) {
            isDone = true;
            lock.notifyAll();
        }

    }


    public DownLinkResult get(long timeoutMillis) {
        DownLinkResult result = new DownLinkResult();
        if (!isDone) {
            synchronized (lock) {
                try {
                    lock.wait(timeoutMillis);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        if (isDone) {
        }
        if(code == 0){
            if(DeviceConstant.LORAWAN.equals(abstractBlockData.getProtocol())){
                code= ResultConstant.SWITCH_LORAWAN_TIMEOUT.getCode();
                result.setCode(code);
            }else {
                result.setCode(code);
            }
        }else {
            result.setData(this.result);
        }
        return result;
    }
}
